/* EasyWay Game Engine
 * Copyright (C) 2006 Daniele Paggi.
 *  
 * Written by: 2006 Daniele Paggi<dshnt@hotmail.com>
 *   
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public License
 * as published by the Free Software Foundation; either version 2 of
 * the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Library General Public License for more details.
 * 
 * You should have received a copy of the GNU Library General Public
 * License along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
package org.easyway.lists;

import java.io.Serializable;

import org.easyway.interfaces.extended.ILayer;
import org.easyway.utils.Utility;

/** gestore delle liste degli sprite (AUTO-USATO DAL SIS. G) */
public class LayerList<T extends ILayer> extends BaseList<T> implements
		Serializable {
	static final long serialVersionUID = 102;

	/** Max- Layer */
	private int maxD;

	/** Min- Layer */
	private int minD;

	/** creates a new instace of LayerList */
	public LayerList() {
		super(false);
		minD = maxD = 0;
		type.set("$_LAYERLIST");
	}

	/** adds a baseobject in the correct location (relative of the layer) */
	public void add(T obj) {
		// ILayer lobj = (ILayer) obj;
		int objlay = obj.getLayer();
		if (minD == maxD) {
			if (size() == 0) {
				minD = maxD = objlay;
			}
			// assert objlay == minD;
			if (objlay == minD) {
				super.add(obj);
				return;
			}
		}
		if (objlay <= minD) {
			minD = objlay;
			super.add(obj);
			return;
		}
		if (objlay >= maxD) {
			maxD = objlay;
			super.add(obj, 0);
			return;
		}
		int size = size(); // 0.3.1

		for (int i = 0; i < size; ++i) {
			if (get(i).getLayer() < objlay) {
				super.add(obj, i);
				return;
			}
		}
		Utility.error("bug in the LayerList! info: mind:" + minD + " max:"
				+ maxD + " current:" + objlay, "LayerList.add( BaseObject )");
		System.out.println("min " + minD + " max " + maxD);
		assert false : "bug in the layerList";
	}

	/** finds the max and min layer used */
	private void generateMaxMin() {
		/*
		 * maxD = minD = 0; for (int i = 0; i < size(); i++) { int d; if ((d =
		 * ((ILayer)get(i)).getLayer()) > maxD) maxD = d; else if (d < minD)
		 * minD = d; }
		 */
		if (size() >= 1) {
			maxD = get(0).getLayer();
			minD = get(size() - 1).getLayer();
		} else
			maxD = minD = 0;
	}

	/**
	 * destroys all object of type specified
	 * 
	 * @see #remove(String)
	 */
	// public void destroy(String type) {
	// super.destroy(type);
	// generateMaxMin();
	// }
	/**
	 * destroys all object from the list
	 * 
	 * @see #removeAll()
	 */
	public void destroyAll() {
		super.destroyAll();
		maxD = minD = 0;
	}

	// -----------------------------------------
	/**
	 * removes the object of 'index' position form the list
	 */
	public void remove(int index) {
		if (get(index) == null) {
			// new Exception().printStackTrace();
			Utility.error("finded a null reference", "LayerList.remove(int)");
			return;
		}
		// int val = temp.getLayer();
		super.remove(index);
		if (size() >= 1) {
			// if (val == maxD) {// 0.1.9
			maxD = get(0).getLayer();
			// } else if (val == minD) { // 0.1.9
			minD = get(size() - 1).getLayer();
			// } // 0.1.9
		} else {
			maxD = minD = 0;
		}
	}

	public void remove(T obj) {
		// ILayer temp = (ILayer) obj;
		if (obj == null) {
			// new Exception().printStackTrace();
			Utility
					.error("finded a null reference",
							"LayerList.remove(ILayer)");
			return;
		}
		// int val = temp.getLayer();
		super.remove(obj);
		if (size() >= 1) {// 0.1.9
			// if (val == maxD) {// 0.1.9
			maxD = ((ILayer) get(0)).getLayer();
			// } else if (val == minD) {// 0.1.9
			minD = ((ILayer) get(size() - 1)).getLayer();
			// }// 0.1.9
		} else {
			maxD = minD = 0;
		}
	}

	/**
	 * removes a sub-range of objects
	 * 
	 * @param from
	 *            the start index
	 * @param to
	 *            the end index
	 */
	public void remove(int from, int to) {
		for (int i = to; i >= from; --i) {
			super.remove(i);
		}
		generateMaxMin();
	}

	/**
	 * removes all object of type specified
	 * 
	 * @see #destroy(String)
	 */
	// public void remove(String type) {
	// super.remove(type);
	// generateMaxMin();
	// }
	/**
	 * removes all objects from the lists
	 * 
	 * @see #destroyAll()
	 */
	public void removeAll() {
		super.removeAll();
		maxD = minD = 0;
	}

}